#!/bin/bash
#
# Comando "LoguearT"
#
# PURPOSE: Este script es usado para dejar constancia de cada mensaje de error
#	   o informativo que puedan ser generados en las distintas funciones
#	   del trabajo práctico.
# OUTPUT:
# 	Archivo de Log
#
# OPCIONES Y PARÁMETROS:
#	Parámetro 1 (obligatorio): comando
#	Parámetro 2 (obligatorio): tipo de mensaje
#	Parámetro 3 (obligatorio): mensaje
#
# CODIGOS DE ERROR:
#	1 - Archivo duplicado.
#	2 - Archivo inexistente.
#	3 - Cantidad de parámetros inválida.
#	4 - Archivo Maestro no encontrado.
#	5 - La dirección del directorio de destino es un archivo.
#	6 - Tipo de mensaje de error inválido.
#	7 - 
# 	8 - Variables de entorno no definidas
#	9 - Directorio inexistente
#	10 - PERL no esta instalado
#	11 - El demonio no pudo ser inicializado
#	12 - El demonio ya se encuentra inicializado
#	13 - Número de error inexistente
#
######################################################
# Constantes
######################################################

CANT_PARAM=3
MAX_LONG_MENSAJE=140

######################################################
# Valores por default
######################################################
DEFAULT_EXT="log"
DEFAULT_LOGSIZE=100
######################################################
# Vector con los errores posibles (Índide base=0).
######################################################

declare -a ERRORES=(
"E1: Archivo duplicado."
"E2: Archivo inexistente."
"E3: Cantidad de parámetros inválida."
"E4: Archivo Maestro no encontrado."
"E5: La dirección del directorio de destino es un archivo."
"E6: Tipo de mensaje de error inválido."
"E7: "
"E8: Variables de entorno no definidas"
"E9: Directorio inexistente"
"E10: PERL no esta instalado"
"E11: El demonio no pudo ser inicializado"
"E12: El demonio ya se encuentra inicializado"
"E13: Número de error inexistente"
);

######################################################
# La siguiente funcion muestra un ejemplo de ayuda en
# el caso de que hubiese habido algún error en los
# parámetros ingresados.
######################################################

function help_LoguearT()
{
  echo " "
  echo "Uso: $(basename $0) <comando> {I|A|E|SE} <codigo_error>"
  echo " "
  echo " ************ Tipo de Mensaje ************"
  echo "    I    INFORMATIVO"
  echo "    A    ALERTA"
  echo "    E    ERROR"
  echo "    SE   ERROR SEVERO"
  echo " "
  echo " ***********  Codigo de Error **************"
  echo "  -- Debe usar los codigos de error provistos en la documentación"
  echo " "
  echo "Ejemplo: $(basename $0) comando A 1"

}

######################################################
# Chequeo del número de parámetros.
######################################################

if [ $# != $CANT_PARAM ] # Los parámetros de entrada deben ser 3
then
	help_LoguearT
	$0 LoguearT E 3
	exit 1
fi

######################################################
# Definición de variables.
######################################################

logdir=""
mensaje=""
tipoMensaje=""
fecha=""

######################################################
# De tratarse de un log proveniente del instalador,
# éste debe ser escrito en otro archivo dedicado solo
# a los mensajes del instalador.
# Verifico que las variables de entorno necesarias
# esten definidas.
######################################################

if [ "$1" == "InstalarT" ]
then
	if [ -z "$CONFDIR" ]
	then
		echo "${ERRORES[7]}"
		exit 1
	fi
    logdir="$CONFDIR"
elif [ ! -z "$GRUPO" ]
then
	if [ -z "$LOGDIR" ]
	then
	   	logdir="$GRUPO/logdir"	
	else
	   	logdir="$LOGDIR"
	fi
else
	echo "${ERRORES[7]}"
	exit 1
fi

######################################################
# Se comprueba que la dirección pasada por parámetro
# sea un directorio y no un archivo.
######################################################

if [ -f "$logdir" ]
then
	$0 LoguearT E 5
	exit 1
fi

######################################################
# En caso de que el directorio no exista, el mismo
# es creado.
######################################################

if [ ! -d "$logdir" ]
then
	mkdir $logdir
fi

######################################################
# En caso de que la extensión del archivo de Log no
# esté definida en la variable $LOGEXT, la extensión
# por default será "log".
######################################################

if [ -z "$LOGEXT" ]
then
	log="$logdir/$1.$DEFAULT_EXT"
else
	log="$logdir/$1$LOGEXT"
fi

######################################################
# Convierto a mayúsculas el segundo parámetro, que es 
# el referido al tipo de mensaje, y lo identifico.
# En caso de tratarse de un tipo de mensaje inválido,
# dicho error también es agregado al log.
######################################################

tipoMensaje=$(echo $2 | tr "[:lower:]" "[:upper:]")
case $tipoMensaje in
I)
  ;;
A)
  ;;
E)
  ;;
SE)
  ;;
*)
  echo "${ERRORES[5]}"
  $0 LoguearT E 6
  help_LoguearT
  exit 1
  ;;
esac

######################################################
# Si el mensaje es del tipo error o error severo, 
# verifico que el código de error exista. 
# En caso de tratarse de un código de error inválido,
# dicho error también es agregado al log.
######################################################

if [ "$tipoMensaje" == "E" -o "$tipoMensaje" == "SE" ]
then
	codError=$(echo "$3" | grep "^[0-9]*$" )
	if [ ! -z $codError ] && [ $codError -le ${#ERRORES[*]} ]
	then
		let indice=$3-1
		mensaje="${ERRORES[$indice]}"
	else
		echo "${ERRORES[12]}"
		$0 LoguearT E 13
		help_LoguearT
		exit 1
	fi
else
    mensaje="$3"
fi

if [ -f "$log" ]
then
	tamanioArchivo=`stat -c%s $log`
else
	touch $log
	tamanioArchivo=0
fi

######################################################
# Primero se elimina cualquier caracter que no sea numérico
# o letra, además de espacios sobrantes y guiones(éstos son
# utilizados como separadores de campo en los archivos de log).
# Si la longitud del mensaje excede $MAX_LONG_MENSAJE,
# este pasa a ser parseado en mensajes con longitudes
# menores a $MAX_LONG_MENSAJE.
######################################################

mensaje=$(echo "$mensaje" | sed -e 's/[^A-Za-z0-9@%!/(): .]//g' -e 's/-/ /g' -e 's/\s\{2,\}/ /g' -e 's/^\s//' -e 's/\s$//')

if [ -z "$mensaje" ]
then
  exit 1
fi

cantChars=1
while [ ${#mensaje} -gt $MAX_LONG_MENSAJE ]
do
  posDondeCortar=$MAX_LONG_MENSAJE
  while [[ $posDondeCortar > 0 && "${mensaje:$posDondeCortar:cantChars}" != $'\n' && "${mensaje:$posDondeCortar:cantChars}" != $' ' ]]
  do
    posDondeCortar=`expr $posDondeCortar - 1`
  done
  mensajeAux=${mensaje:0:$posDondeCortar}
  mensaje=${mensaje:`expr $posDondeCortar + 1`}
  $0 "$1" "$2" "$mensajeAux"
done

######################################################
# Si el tamaño del archivo de logs excede el tamaño
# máximo estipulado, se debe reducir el tamaño del
# mismo. Además, se escribe en el archivo de logs del
# LoguearT un mensaje de Log excedido.
######################################################

if [ -z $LOGSIZE ]
then
	LOGSIZE=$DEFAULT_LOGSIZE
fi

let LOGSIZEBYTES=$LOGSIZE*1024
if [ $tamanioArchivo -ge $LOGSIZEBYTES ]
then
	mensajeExcedido="Log Excedido"
	# Paso una copia temporal del archivo de Log a un archivo nuevo,
	# borro el archivo antiguo y luego lo renombro.
	lineas=`wc -l $log | cut -d ' ' -f 1`
	lineas=`expr $lineas \* 50`
	lineas=`expr $lineas / 100`		
	logtemp=$log.temp
	tail -q -n $lineas $log > $logtemp
	rm $log
	mv $logtemp $log
	$0 $1 I "$mensajeExcedido"
fi

######################################################
# Se escribe el archivo.  
######################################################

fecha=`date +"%x %X"`
echo "$fecha-$(whoami)-$1-$tipoMensaje-$mensaje" >> $log

exit 0 
